﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Mail;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.IO;

namespace EmailTool
{
    /// <summary>
    /// 邮件发送帮助类
    /// </summary>
    public class EmailHelper
    {
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="emo">邮件内容</param>
        /// <param name="err">错误信息</param>
        public static bool SendNetMail(EmailParaModel emo, out Exception err)
        {
            err = null;
            try
            {
                NetEmailClient xEmailClient = new NetEmailClient(emo.UserName, emo.Password, emo.Host, emo.Port, emo.EnableSsl, emo.MailFrom, emo.MailFromName);
                xEmailClient.Subject = emo.Subject;//主题
                xEmailClient.Body = emo.Body;//内容
                xEmailClient.BodyEncoding = System.Text.Encoding.Default;//正文编码
                xEmailClient.IsBodyHtml = emo.IsBodyHtml;//设置为HTML格式
                xEmailClient.Priority = System.Net.Mail.MailPriority.Normal;//优先级
                xEmailClient.AddAttachments(emo.AttachFiles);
                xEmailClient.Send(emo.MailTo, emo.MailCc);
            }
            catch (Exception ex)
            {
                err = ex;
                return false;
            }
            return true;
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="emo">邮件内容</param>
        /// <param name="err">错误信息</param>
        public static bool SendWebMail(EmailParaModel emo, out Exception err)
        {
            err = null;
            try
            {
                WebEmailClient xEmailClient = new WebEmailClient(emo.UserName, emo.Password, emo.Host, emo.Port, emo.EnableSsl, emo.MailFrom, emo.MailFromName);
                xEmailClient.Subject = emo.Subject;//主题
                xEmailClient.Body = emo.Body;//内容
                xEmailClient.BodyEncoding = emo.BodyEncoding;//正文编码
                xEmailClient.IsBodyHtml = emo.IsBodyHtml;//设置为HTML格式
                xEmailClient.Priority = (System.Web.Mail.MailPriority)emo.Priority;//优先级
                xEmailClient.AddAttachments(emo.AttachFiles);
                xEmailClient.Send(emo.MailTo, emo.MailCc);
            }
            catch (Exception ex)
            {
                err = ex;
                return false;
            }
            return true;
        }
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="emo">邮件内容</param>
        /// <param name="completedEvent">处理完成回调</param>
        public static void SendNetMailAsync(EmailParaModel emo, EventHandler<AsyncCompletedEventArgs> completedEvent)
        {
            NetEmailClient xEmailClient = new NetEmailClient(emo.UserName, emo.Password, emo.Host, emo.Port, emo.EnableSsl, emo.MailFrom, emo.MailFromName);
            xEmailClient.Subject = emo.Subject;//主题
            xEmailClient.Body = emo.Body;//内容
            xEmailClient.BodyEncoding = System.Text.Encoding.Default;//正文编码
            xEmailClient.IsBodyHtml = emo.IsBodyHtml;//设置为HTML格式
            xEmailClient.Priority = (System.Net.Mail.MailPriority)emo.Priority;//优先级
            xEmailClient.SendAsyncCompleted += new EventHandler<AsyncCompletedEventArgs>(completedEvent);
            xEmailClient.AddAttachments(emo.AttachFiles);
            xEmailClient.SendAsync(emo.MailTo, emo.MailCc);
        }

        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="emo">邮件内容</param>
        /// <param name="completedEvent">发送完成回调</param>
        public static void SendWebMailAsync(EmailParaModel emo, EventHandler<AsyncCompletedEventArgs> completedEvent)
        {
            WebEmailClient xEmailClient = new WebEmailClient(emo.UserName, emo.Password, emo.Host, emo.Port, emo.EnableSsl, emo.MailFrom, emo.MailFromName);
            xEmailClient.Subject = emo.Subject;//主题
            xEmailClient.Body = emo.Body;//内容
            xEmailClient.BodyEncoding = emo.BodyEncoding;//正文编码
            xEmailClient.IsBodyHtml = emo.IsBodyHtml;//设置为HTML格式
            xEmailClient.Priority = (System.Web.Mail.MailPriority)emo.Priority;//优先级
            xEmailClient.SendAsyncCompleted += new EventHandler<AsyncCompletedEventArgs>(completedEvent);
            xEmailClient.AddAttachments(emo.AttachFiles);
            xEmailClient.SendAsync(emo.MailTo, emo.MailCc);
        }
    }
    /// <summary>
    /// 邮件基础内容实体类
    /// </summary>
    [Serializable]
    public class EmailParaModel
    {
        private string _smtpServer = "smtp.qq.com";
        private int _port = 587;
        private string _userName = string.Empty;
        private string _password = string.Empty;
        private string _mailFromName = string.Empty;
        private string _mailFrom = string.Empty;
        private string _mailTo = string.Empty;
        private string _mailToName = string.Empty;
        private string _mailCC = null;
        private string _subject = string.Empty;
        private string _body = string.Empty;
        private Encoding _bodyEncoding = System.Text.Encoding.Default;
        private bool _isBodyHtml = true;
        private int _priority = 0;
        private Dictionary<string, string> _attachFiles = null;
        public EmailParaModel()
        {

        }
        /// <summary>
        /// SMTP服务器
        /// </summary>
        public string Host
        {
            get { return _smtpServer; }
            set { _smtpServer = value; }
        }
        /// <summary>
        /// 端口号
        /// </summary>
        public int Port
        {
            get { return _port; }
            set { _port = value; }
        }
        /// <summary>
        /// 登录帐号
        /// </summary>
        public string UserName
        {
            get { return _userName; }
            set { _userName = value; }
        }
        /// <summary>
        /// 账号密码
        /// </summary>
        public string Password
        {
            get { return _password; }
            set { _password = value; }
        }
        public bool EnableSsl { get; set; }
        /// <summary>
        /// 发件人名
        /// </summary>
        public string MailFromName
        {
            get { return _mailFromName; }
            set { _mailFromName = value; }
        }
        /// <summary>
        /// 发件人
        /// </summary>
        public string MailFrom
        {
            get { return _mailFrom; }
            set { _mailFrom = value; }
        }
        /// <summary>
        /// 收件人
        /// </summary>
        public string MailTo
        {
            get { return _mailTo; }
            set { _mailTo = value; }
        }
        /// <summary>
        /// 收件人名
        /// </summary>
        public string MailToName
        {
            get { return _mailToName; }
            set { _mailToName = value; }
        }
        /// <summary>
        /// 主题
        /// </summary>
        public string Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }
        /// <summary>
        /// 内容
        /// </summary>
        public string Body
        {
            get { return _body; }
            set { _body = value; }
        }


        /// <summary>
        /// 正文编码
        /// </summary>
        public Encoding BodyEncoding
        {
            get { return _bodyEncoding; }
            set { _bodyEncoding = value; }
        }

        /// <summary>
        /// 是否为html内容
        /// </summary>
        public bool IsBodyHtml
        {
            get { return _isBodyHtml; }
            set { _isBodyHtml = value; }
        }

        /// <summary>
        /// 邮件优先级：0正常；1低级；2紧急；默认为 0正常
        /// </summary>
        public int Priority
        {
            get { return _priority; }
            set { _priority = value; }
        }
        /// <summary>
        /// 抄送人
        /// </summary>
        public string MailCc
        {
            get { return _mailCC; }
            set { _mailCC = value; }
        }
        /// <summary>
        /// 邮件附件 
        /// key:附件名称；value:附件物理绝对路径
        /// </summary>

        public Dictionary<string, string> AttachFiles
        {
            get { return _attachFiles; }
            set { _attachFiles = value; }
        }
    }

    #region 邮件客户端
    /// <summary>
    /// 邮件客户端 System.Net
    /// 非 Implicit SSL 邮箱适用 非465端口，如25、993
    /// </summary>
    public class NetEmailClient
    {
        #region private
        private readonly System.Net.Mail.MailMessage _mailMessage;   //处理发送邮件的内容（如：收发人地址、标题、主体、图片、附件）
        private readonly System.Net.Mail.SmtpClient _smtpClient;     //处理用smtp方式发送此邮件的配置信息（如：邮件服务器、发送端口号、验证方式）
        private EventHandler<AsyncCompletedEventArgs> m_OnSendCompleted = null;
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="username">发件邮箱</param>
        /// <param name="password">发件邮箱的密码</param>
        /// <param name="server">发件箱的邮件服务器地址</param>
        /// <param name="port">发送邮件所用的端口号（stmp协议默认为25）</param>
        /// <param name="sslEnable">true表示对邮件内容进行ssl加密传输，false表示不加密</param>
        public NetEmailClient(string username, string password, string server, int port, bool sslEnable)
        {
            _smtpClient = new System.Net.Mail.SmtpClient(server, port);
            _smtpClient.EnableSsl = sslEnable;
            _smtpClient.UseDefaultCredentials = false;
            _smtpClient.Credentials = new System.Net.NetworkCredential(username, password);//用户名和密码
            _smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;//指定电子邮件发送方式
            _smtpClient.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(m_SendCompleted);

            _mailMessage = new System.Net.Mail.MailMessage();
            _mailMessage.IsBodyHtml = true;
            _mailMessage.BodyEncoding = Encoding.UTF8;
            _mailMessage.Priority = System.Net.Mail.MailPriority.Normal;//优先级
            _mailMessage.From = new System.Net.Mail.MailAddress(username);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="username">发件邮箱</param>
        /// <param name="password">发件邮箱的密码</param>
        /// <param name="server">发件箱的邮件服务器地址</param>
        /// <param name="port">发送邮件所用的端口号（stmp协议默认为25）</param>
        /// <param name="sslEnable">true表示对邮件内容进行ssl加密传输，false表示不加密</param>
        /// <param name="fromAddress">发件人邮箱地址</param>
        /// <param name="displayName">发件人显示名称</param>
        public NetEmailClient(string username, string password, string server, int port, bool sslEnable, string fromAddress, string displayName)
        {
            _smtpClient = new System.Net.Mail.SmtpClient(server, port);
            _smtpClient.EnableSsl = sslEnable;
            _smtpClient.UseDefaultCredentials = false;
            _smtpClient.Credentials = new System.Net.NetworkCredential(username, password);//用户名和密码
            _smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;//指定电子邮件发送方式
            _smtpClient.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(m_SendCompleted);

            _mailMessage = new System.Net.Mail.MailMessage();
            _mailMessage.IsBodyHtml = true;
            _mailMessage.BodyEncoding = Encoding.UTF8;
            _mailMessage.Priority = System.Net.Mail.MailPriority.Normal;//优先级
            if (string.IsNullOrEmpty(displayName))
                _mailMessage.From = new System.Net.Mail.MailAddress(fromAddress);
            else
                _mailMessage.From = new System.Net.Mail.MailAddress(fromAddress, displayName, Encoding.UTF8);
        }

        #endregion

        #region 私有函数

        /// <summary>
        /// SmtpClient异步发送完成时回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (m_OnSendCompleted != null)
            {
                this.m_OnSendCompleted.Invoke(sender, e);
            }
        }

        /// <summary>
        /// 格式化多邮箱字地址
        /// </summary>
        /// <param name="toEmail"></param>
        /// <returns></returns>
        private IEnumerable<System.Net.Mail.MailAddress> FormatMailAddress(string toEmail)
        {
            return Regex.Replace(toEmail, @"[；;,]", "|").Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries).Select(x => new System.Net.Mail.MailAddress(x, x));
        }

        #endregion

        #region 公共属性
        /// <summary>
        /// 
        /// </summary>
        public System.Net.Mail.MailMessage MailMessage
        {
            get { return _mailMessage; }
        }
        /// <summary>
        /// 邮件发送异步完成回调事件
        /// </summary>
        public event EventHandler<AsyncCompletedEventArgs> SendAsyncCompleted
        {
            add { m_OnSendCompleted += value; }
            remove { m_OnSendCompleted -= value; }
        }
        /// <summary>
        /// 发件人信息
        /// </summary>
        public System.Net.Mail.MailAddress From
        {
            get { return _mailMessage.From; }
            set { _mailMessage.From = value; }
        }

        /// <summary>
        /// 邮件主题
        /// </summary>
        public string Subject
        {
            get { return _mailMessage.Subject; }
            set { _mailMessage.Subject = value; }
        }

        /// <summary>
        /// 邮件内容
        /// </summary>
        public string Body
        {
            get { return _mailMessage.Body; }
            set { _mailMessage.Body = value; }
        }

        /// <summary>
        /// 正文编码
        /// </summary>
        public Encoding BodyEncoding
        {
            get { return _mailMessage.BodyEncoding; }
            set { _mailMessage.BodyEncoding = value; }
        }

        /// <summary>
        /// 是否为html内容
        /// </summary>
        public bool IsBodyHtml
        {
            get { return _mailMessage.IsBodyHtml; }
            set { _mailMessage.IsBodyHtml = value; }
        }

        /// <summary>
        /// 邮件优先级：低、正常、紧急，默认为 正常
        /// </summary>
        public System.Net.Mail.MailPriority Priority
        {
            get { return _mailMessage.Priority; }
            set { _mailMessage.Priority = value; }
        }

        /// <summary>
        /// 收件人信息
        /// </summary>
        public string To
        {
            get { return string.Join(";", _mailMessage.To?.Select(x => x.Address)); }
            set
            {
                _mailMessage.To.Clear();
                var maillist = FormatMailAddress(value);
                foreach (var item in maillist)
                {
                    _mailMessage.To.Add(item);
                }
            }
        }

        /// <summary>
        /// 抄送人信息
        /// </summary>
        public string CC
        {
            get { return string.Join(";", _mailMessage.CC?.Select(x => x.Address)); }
            set
            {
                _mailMessage.CC.Clear();
                var maillist = FormatMailAddress(value);
                foreach (var item in maillist)
                {
                    _mailMessage.CC.Add(item);
                }
            }
        }
        #endregion

        #region 公共函数

        ///<summary>
        /// 添加附件
        ///</summary>
        ///<param name="opfiles">附件的路径集合</param>
        public void AddAttachments(IDictionary<string, string> opfiles)
        {
            if (opfiles != null && opfiles.Count > 0)
            {
                foreach (var item in opfiles)
                {
                    var data = new System.Net.Mail.Attachment(item.Value, System.Net.Mime.MediaTypeNames.Application.Octet);
                    data.Name = item.Key;
                    var disposition = data.ContentDisposition;
                    disposition.CreationDate = System.IO.File.GetCreationTime(item.Value);
                    disposition.ModificationDate = System.IO.File.GetLastWriteTime(item.Value);
                    disposition.ReadDate = System.IO.File.GetLastAccessTime(item.Value);
                    _mailMessage.Attachments.Add(data);
                }
            }
        }

        ///<summary>
        /// 添加内联附件
        /// 不显示在附件里，直接可以用id显示在html内容中，一般用于图片附件
        /// 可以用文件id<img src=\"cid:webimg\">嵌入html
        ///</summary>
        ///<param name="opfiles">附件的路径集合</param>
        public void AddAttachmentsInside(IDictionary<string, string> opfiles)
        {
            if (opfiles != null && opfiles.Count > 0)
            {
                foreach (var item in opfiles)
                {
                    var data = new System.Net.Mail.Attachment(item.Value, System.Net.Mime.MediaTypeNames.Application.Octet);
                    data.Name = item.Key;
                    var disposition = data.ContentDisposition;
                    data.ContentDisposition.CreationDate = System.IO.File.GetCreationTime(item.Value);
                    data.ContentDisposition.ModificationDate = System.IO.File.GetLastWriteTime(item.Value);
                    data.ContentDisposition.ReadDate = System.IO.File.GetLastAccessTime(item.Value);
                    data.ContentId = System.IO.Path.GetFileNameWithoutExtension(item.Value);
                    _mailMessage.Attachments.Add(data);
                }
            }

        }

        /// <summary>
        /// 清除附件
        /// </summary>
        public void ClearAttachments()
        {
            _mailMessage.Attachments.Clear();
        }
        /// <summary>
        /// 发送邮件（同步方法，发送异常时抛出）
        /// </summary>
        public void Send()
        {
            Send(_mailMessage.To, _mailMessage.CC);
        }
        /// <summary>
        /// 发送邮件（同步方法，发送异常时抛出）
        /// </summary>
        /// <param name="toEmail">收件人</param>
        /// <param name="toEmailCc">抄送人</param>
        public void Send(string toEmail, string toEmailCc)
        {
            Send(FormatMailAddress(toEmail), FormatMailAddress(toEmailCc));
        }

        /// <summary>
        /// 批量发送邮件（同步方法，发送异常时抛出）
        /// </summary>
        /// <param name="toEmailList">收件人集合</param>
        /// <param name="toEmailCcList">抄送人集合</param>
        public void Send(IEnumerable<System.Net.Mail.MailAddress> toEmailList, IEnumerable<System.Net.Mail.MailAddress> toEmailCcList)
        {
            _mailMessage.To.Clear();
            foreach (var item in toEmailList)
            {
                _mailMessage.To.Add(item);
            }
            _mailMessage.CC.Clear();
            foreach (var item in toEmailCcList)
            {
                _mailMessage.CC.Add(item);
            }
            _smtpClient.Send(_mailMessage);
        }

        /// <summary>
        /// 发送邮件（异步方法，发送异常时回调中返回）
        /// </summary>
        /// <returns></returns>
        public Task SendAsync()
        {
            return SendAsync(_mailMessage.To, _mailMessage.CC);
        }

        /// <summary>
        /// 发送邮件（异步方法，发送异常时回调中返回）
        /// </summary>
        /// <param name="toEmail">收件人</param>
        /// <param name="toEmailCc">抄送人</param>
        public Task SendAsync(string toEmail, string toEmailCc)
        {
            return SendAsync(FormatMailAddress(toEmail), FormatMailAddress(toEmailCc));
        }

        /// <summary>
        /// 批量发送邮件（异步方法，发送异常时回调中返回）
        /// </summary>
        /// <param name="toEmailObjList">收件人集合</param>
        /// <returns></returns>
        public Task SendAsync(IEnumerable<System.Net.Mail.MailAddress> toEmailList, IEnumerable<System.Net.Mail.MailAddress> toEmailCcList)
        {
            _mailMessage.To.Clear();
            foreach (var item in toEmailList)
            {
                _mailMessage.To.Add(item);
            }
            _mailMessage.CC.Clear();
            foreach (var item in toEmailCcList)
            {
                _mailMessage.CC.Add(item);
            }
            return _smtpClient.SendMailAsync(_mailMessage);
        }

        /// <summary>
        /// 发送邮件（异步方法，发送异常时回调中返回）
        /// </summary>
        /// <param name="toEmail">收件人</param>
        /// <param name="toEmailCc">抄送人</param>
        /// <param name="userToken"></param>
        public void SendAsync(string toEmail, string toEmailCc, object userToken)
        {
            SendAsync(FormatMailAddress(toEmail), FormatMailAddress(toEmailCc), userToken);
        }

        /// <summary>
        /// 批量发送邮件（异步方法，发送异常时回调中返回）
        /// </summary>
        /// <param name="toEmailObjList">收件人集合</param>
        /// <param name="userToken"></param>
        public void SendAsync(IEnumerable<System.Net.Mail.MailAddress> toEmailObjList, IEnumerable<System.Net.Mail.MailAddress> toEmailCcObjList, object userToken)
        {
            _mailMessage.To.Clear();
            foreach (var item in toEmailObjList)
            {
                _mailMessage.To.Add(item);
            }
            _mailMessage.CC.Clear();
            foreach (var item in toEmailCcObjList)
            {
                _mailMessage.CC.Add(item);
            }
            _smtpClient.SendAsync(_mailMessage, userToken);
        }
        #endregion
    }
    /// <summary>
    /// 邮件客户端 System.Web
    /// 一般用于 Implicit SSL 的邮箱服务 465端口
    /// </summary>
    public class WebEmailClient
    {
        #region 私有函数
        private readonly System.Web.Mail.MailMessage _mailMessage;   //处理发送邮件的内容（如：收发人地址、标题、主体、图片、附件）
        private EventHandler<AsyncCompletedEventArgs> m_OnSendCompleted = null;
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="username">发件邮箱</param>
        /// <param name="password">发件邮箱的密码</param>
        /// <param name="server">发件箱的邮件服务器地址</param>
        /// <param name="port">发送邮件所用的端口号（stmp协议默认为25）</param>
        /// <param name="sslEnable">true表示对邮件内容进行ssl加密传输，false表示不加密</param>
        public WebEmailClient(string username, string password, string server, int port, bool sslEnable)
        {
            _mailMessage = new System.Web.Mail.MailMessage();
            _mailMessage.BodyFormat = System.Web.Mail.MailFormat.Text;
            _mailMessage.BodyEncoding = Encoding.UTF8;
            _mailMessage.Priority = System.Web.Mail.MailPriority.High;//优先级

            _mailMessage.Fields.Add("server", server);
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", username);//登陆名  
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", password);//登陆密码  
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", port);//端口 
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", sslEnable.ToString().ToLower());
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="username">发件邮箱</param>
        /// <param name="password">发件邮箱的密码</param>
        /// <param name="server">发件箱的邮件服务器地址</param>
        /// <param name="port">发送邮件所用的端口号（stmp协议默认为25）</param>
        /// <param name="sslEnable">true表示对邮件内容进行ssl加密传输，false表示不加密</param>
        /// <param name="fromAddress">发件人地址</param>
        /// <param name="displayName">发件人名称</param>
        public WebEmailClient(string username, string password, string server, int port, bool sslEnable, string fromAddress, string displayName)
        {

            _mailMessage = new System.Web.Mail.MailMessage();
            _mailMessage.BodyFormat = System.Web.Mail.MailFormat.Text;
            _mailMessage.BodyEncoding = Encoding.UTF8;
            _mailMessage.Priority = System.Web.Mail.MailPriority.High;//优先级
            _mailMessage.From = fromAddress ?? displayName;

            _mailMessage.Fields.Add("server", server);
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", username);//登陆名
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", password);//登陆密码  
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", port);//端口 
            _mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", sslEnable.ToString().ToLower());
        }

        #endregion

        #region 私有函数

        /// <summary>
        /// SmtpClient异步发送完成时回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void m_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (m_OnSendCompleted != null)
            {
                this.m_OnSendCompleted.Invoke(sender, e);
            }
        }

        /// <summary>
        /// 格式化多邮箱字地址
        /// </summary>
        /// <param name="toEmail"></param>
        /// <returns></returns>
        private string FormatMailAddress(string toEmail)
        {
            return string.Join(";", Regex.Replace(toEmail, @"[；;,]", "|").Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries));
        }

        #endregion

        #region 公共属性
        /// <summary>
        /// 
        /// </summary>
        public System.Web.Mail.MailMessage MailMessage
        {
            get { return _mailMessage; }
        }
        /// <summary>
        /// 邮件发送完成回调事件
        /// </summary>
        public event EventHandler<AsyncCompletedEventArgs> SendAsyncCompleted
        {
            add { m_OnSendCompleted += value; }
            remove { m_OnSendCompleted -= value; }
        }

        /// <summary>
        /// 发件人信息
        /// </summary>
        public string From
        {
            get { return _mailMessage.From; }
            set { _mailMessage.From = value; }
        }

        /// <summary>
        /// 邮件主题
        /// </summary>
        public string Subject
        {
            get { return _mailMessage.Subject; }
            set { _mailMessage.Subject = value; }
        }

        /// <summary>
        /// 邮件内容
        /// </summary>
        public string Body
        {
            get { return _mailMessage.Body; }
            set { _mailMessage.Body = value; }
        }

        /// <summary>
        /// 正文编码
        /// </summary>
        public Encoding BodyEncoding
        {
            get { return _mailMessage.BodyEncoding; }
            set { _mailMessage.BodyEncoding = value; }
        }

        /// <summary>
        /// 是否为html内容
        /// </summary>
        public bool IsBodyHtml
        {
            get { return _mailMessage.BodyFormat == System.Web.Mail.MailFormat.Html; }
            set { _mailMessage.BodyFormat = value ? System.Web.Mail.MailFormat.Html : System.Web.Mail.MailFormat.Text; }
        }


        /// <summary>
        /// 邮件优先级：低、正常、紧急，默认为 正常
        /// </summary>
        public System.Web.Mail.MailPriority Priority
        {
            get { return _mailMessage.Priority; }
            set { _mailMessage.Priority = value; }
        }

        /// <summary>
        /// 收件人信息
        /// </summary>
        public string To
        {
            get { return _mailMessage.To; }
            set { _mailMessage.To = FormatMailAddress(value); }
        }

        /// <summary>
        /// 抄送人信息
        /// </summary>
        public string CC
        {
            get { return _mailMessage.Cc; }
            set { _mailMessage.Cc = FormatMailAddress(value); }
        }
        #endregion

        #region 公共函数

        ///<summary>
        /// 添加附件
        ///</summary>
        ///<param name="opfiles">附件的路径集合</param>
        public void AddAttachments(IDictionary<string, string> opfiles)
        {
            if (opfiles != null && opfiles.Count > 0)
            {
                foreach (var item in opfiles)
                {
                    var bytes = System.IO.File.ReadAllBytes(item.Value);
                    var data = new System.Web.Mail.MailAttachment(Convert.ToBase64String(bytes), System.Web.Mail.MailEncoding.Base64);
                    _mailMessage.Attachments.Add(data);
                }
            }
        }

        /// <summary>
        /// 清除附件
        /// </summary>
        public void ClearAttachments()
        {
            _mailMessage.Attachments.Clear();
        }

        /// <summary>
        /// 发送邮件（同步方法，发送异常时抛出）
        /// </summary>
        public void Send()
        {
            Send(_mailMessage.To, _mailMessage.Cc);
        }
        /// <summary>
        /// 发送邮件（同步方式，发送异常时抛出）
        /// </summary>
        /// <param name="toEmail">收件人</param>
        /// <param name="toEmailCc">抄送人</param>
        public void Send(string toEmail, string toEmailCc)
        {
            _mailMessage.To = FormatMailAddress(toEmail);
            _mailMessage.Cc = FormatMailAddress(toEmailCc);
            System.Web.Mail.SmtpMail.SmtpServer = _mailMessage.Fields["server"].ToString();
            System.Web.Mail.SmtpMail.Send(_mailMessage);
        }

        /// <summary>
        /// 发送邮件（同步方法，发送异常时抛出）
        /// </summary>
        public Task SendAsync()
        {
            return SendAsync(_mailMessage.To, _mailMessage.Cc);
        }
        /// <summary>
        /// 发送邮件（异步方式，发送异常时回调中返回）
        /// </summary>
        /// <param name="toEmail">收件人</param>
        /// <param name="toEmailCc">抄送人</param>
        /// <returns></returns>
        public Task SendAsync(string toEmail, string toEmailCc)
        {
            Task task = Task.Factory.StartNew(() =>
            {
                _mailMessage.To = FormatMailAddress(toEmail);
                _mailMessage.Cc = FormatMailAddress(toEmailCc);
                System.Web.Mail.SmtpMail.SmtpServer = _mailMessage.Fields["server"].ToString();
                System.Web.Mail.SmtpMail.Send(_mailMessage);
            });
            task.GetAwaiter().OnCompleted(() => {
                this.m_SendCompleted(task, new AsyncCompletedEventArgs(task.Exception, task.IsCanceled, null));
            });
            return task;
        }
        #endregion
    }
    #endregion
}
